#include <stdio.h>
#include <linux/ioctl.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/time.h>
#include <string.h>
#include <semaphore.h>
#include <getopt.h>
#include <dirent.h>

//数据包包头,包括版本号, 编解码等
typedef struct
{
    unsigned int FrameNO;//帧序号
    unsigned int valid;
    unsigned int sec;
    unsigned int usec;
}pk_hdr_t;

#define BUFFER_COUNT                5 //接收端缓冲区有该数量才允许播放
#define SAMPLERATE              32000 //定义采样率
#define CHANNELS                    1 //单声道采样
#define READMSFORONCE              10 //采样周期(ms)
#define BUFFERNODECOUNT            32 //链表节点个数
unsigned char buffer[sizeof(pk_hdr_t) + SAMPLERATE/1000*CHANNELS*READMSFORONCE*sizeof(short)];
     
/* 
struct AudioBuffer;
typedef struct AudioBuffer
{
    unsigned char buffer[sizeof(pk_hdr_t) + SAMPLERATE/1000*CHANNELS*READMSFORONCE*sizeof(short)];
    struct AudioBuffer  *pNext;
} AUDIOBUFFER;
*/

//#define SERVERIP "192.168.2.114"

struct option long_options[] = {  
     { "version",     0,   NULL,       'v'},
     { "debug",       0,   NULL,       'd'},     
     { "help",        0,   NULL,       'h'},
     { "ipaddr",     1,   NULL,       'i'},
     { "port",  1,   NULL,       'p'},
     { "spkvolume",   1,   NULL,       's'}, 
     {"file",   1,  NULL, 'f'},         
     {      0,        0,      0,        0},  
};  

void usage()
{
   printf ("Usage: sendpcm [options] \n");
   printf ("\n");
   printf (" -d, --debug           set debug\n");   
   printf (" -p, --port            set send port\n");
   printf (" -i, --ipaddr          set ip address\n");
   printf (" -s, --spkvolume       set spkvolume\n");      
   printf (" -h, --help            This help\n");
   printf (" -v, --version         Version information\n");
}

int main(int argc, char **argv)
{
    int c;  
    char* const short_options = "d:p:i:v:f:";      
    int FrameNO = 0;
    struct sockaddr_in dest_addr;
    int result;
    int  serverport = 20000;
    char serverip[15];
    char filename[100];

    while((c = getopt_long(argc, argv, short_options, long_options, NULL)) != -1)  
    {  
        switch (c)  
        {  
            case 'h':
                usage();//帮助
                break;
            case 'd':
                break;			 	
            case 'p':  
                serverport = atoi(optarg);
                break;  
            case 'i':  
                strncpy(serverip, optarg, 15);
                break;  
            case 's':  
                atoi(optarg);
                break;  
            case 'f':
                strncpy(filename, optarg, 99);
                break;
        }  
    }  
    
    printf("send to ip:%s, port:%d,filename=%s\n", serverip, serverport, filename);
    
    FILE * fppcm = fopen(filename, "rb");
    if (!fppcm)
    {
        printf("打开文件:%s\n", filename);
        perror("file open(打开文件)");
        return -1;
    }
    
    
    int fdsocket = socket(AF_INET, SOCK_DGRAM, 0);    
    if (fdsocket == -1) 
    {
      perror("socket(创建套接字)");
      return -1;
    }

    /* 设置远程连接的信息*/
    dest_addr.sin_family = AF_INET;                 /* 注意主机字节顺序*/
    dest_addr.sin_port = htons(serverport);          /* 远程连接端口, 注意网络字节顺序*/
    dest_addr.sin_addr.s_addr = inet_addr(serverip); /* 远程 IP 地址, inet_addr() 会返回网络字节顺序*/
    bzero(&(dest_addr.sin_zero), 8);                /* 其余结构须置 0*/    
    
    while(1)
    {
        result = fread(&buffer[sizeof(pk_hdr_t)], SAMPLERATE/1000*CHANNELS*READMSFORONCE*sizeof(short), 1, fppcm);
        if(!result)
        {
            perror("file read(读文件)");
            fseek(fppcm, 0, SEEK_SET);
        }
        
        ((pk_hdr_t*)buffer)->FrameNO = FrameNO++;
        result = sendto(fdsocket, buffer, sizeof(buffer), 0, (struct sockaddr*)&dest_addr, sizeof(struct sockaddr));    
        if(result == -1)
        {
            perror("sendto(数据发送)");
        }
        
        usleep(10000);
    }
            
    if(fppcm)
    {
        fclose(fppcm);
    }
    return 0;
}
